package com.doyled.jump.user;

import java.awt.Point;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import com.doyled.jump.object.Dice;
import com.doyled.jump.object.Environment;
import com.doyled.jump.object.Horsemen;
import com.doyled.jump.object.Spot;
import com.doyled.jump.util.ChessKind;
import com.doyled.jump.util.TeamInfo;

public class Player extends User {

	private boolean choosing;
	private Horsemen chosenHorse;

	public Player(Environment env, ChessKind kind, TeamInfo teamInfo) {
		super(env, kind, teamInfo);
		this.choosing = false;
	}

	@Override
	public void decide() {
		//check that player has move or not
		if(getMovableHorses().isEmpty() && !canReleaseHorse()){
			endPhrase();
			return;
		}
		
		//do any request from real player
		Point mouseClick = env.getClickPoint();
		if(mouseClick == null) return;
		
		// click in a horse
		Horsemen clickedHorsemen = env.clickInHorse(mouseClick, kind);
		if (clickedHorsemen != null) {
			if (!clickedHorsemen.equals(chosenHorse)) {
				env.hideMovableSpots(env.getMovableSpots(chosenHorse)); // hide
																		// the
																		// movable
																		// spots
																		// of
																		// previous
																		// chosen
																		// horse
				choosing = true;
				List<Spot> movableSpots = env.getMovableSpots(clickedHorsemen); // get
																				// movable
																				// spots
				if(movableSpots.isEmpty()) {
					choosing = false;
					this.chosenHorse = null;
					return; //return if this horse cannot move
				}
				env.showMovableSpots(movableSpots);
				this.chosenHorse = clickedHorsemen;	//store horse to move it later
			}
			return;
		}
		
		// click in start spot
		if (env.clickInStartSpot(mouseClick, kind)) {
			env.hideMovableSpots(env.getMovableSpots(chosenHorse)); // hide the
																	// movable
																	// spots of
																	// previous
																	// chosen
																	// horse
			releaseHorse();
			return;
		}

		if (choosing == true) {
			Spot chosenSpot = env.getClickedSpot(mouseClick);
			List<Spot> movableSpots = env.getMovableSpots(chosenHorse); // get
																			// movable
																			// spots
			if (movableSpots.get(movableSpots.size() - 1).equals(chosenSpot)) {
				env.hideMovableSpots(env.getMovableSpots(chosenHorse)); // hide the movable spots of previous chosen horse
				moveHorse(chosenHorse);
				this.chosenHorse = null;
				choosing = false;
			}
		}
	}

	/**
	 * Throw the dice
	 */
	@Override
	public boolean throwDice(Dice dice) {
		Point mouseClick = env.getClickPoint();
		if (env.clickInDice(mouseClick)) {
			dice.throwDice();
			return true;
		}
		return false;
	}
	
	/**
	 * get our team's horses can move
	 * @return list of horse
	 */
	private List<Horsemen> getMovableHorses(){
		List<Horsemen> movableHorses = new LinkedList<Horsemen>();
		Horsemen[] teamHorses = teamInfo.getHorses();
		for(Horsemen horse : teamHorses){
			if(env.getMovableSpots(horse).size() != 0){
				movableHorses.add(horse);
			}
		}
		return movableHorses;
	}
	
	private boolean canReleaseHorse() {
		int diceNo = env.getDiceNumber();
		Spot startSpot = teamInfo.getStartSpot();
		if((diceNo == 1 || diceNo == 6) && startSpot.getOccupiedChessKind() != teamInfo.getKind()){
			return true;
		}
		return false;
	}

}
